package org.ala.distributed_transaction_commons.communication.coordinator.actions;

import org.ala.distributed_transaction_commons.DistributedTransactionStatus;
import org.ala.distributed_transaction_commons.communication.Message;
import org.ala.distributed_transaction_commons.communication.coordinator.AbstractCoordonatorAction;
import org.ala.distributed_transaction_commons.logs.LoggerFactory;
import org.ala.distributed_transaction_commons.redis.datas.TransactionContext;
import org.slf4j.Logger;

import redis.clients.jedis.Pipeline;


/**
 * 协调者收到rollback消息后做出的响应
 * <p>	当收到rollback消息时，通知所有参与者rollback，修改redis中事务状态为rollback
 * 
 * @author 骆毅(ala)
 * @date 2024年2月18日
 */
public class RollbackAction extends AbstractCoordonatorAction {

	
	static Logger log = LoggerFactory.getLogger("distributed_transaction/cooridinator", "cooridinator");
	
	
	@Override
	public String type() {
		return Message.MSG_TYPE_TO_COORDINATOR_ROLLBACK;
	}

	@Override
	protected void doExecute(TransactionContext context) {
		//	如果当前所有人的信息都是rollback，则清除事务环境
		boolean isAllRollback = context.getParticipantSet().stream().map(c -> DistributedTransactionStatus.ROLLBACK.equals(c.getStatus())).reduce(true, (c1,c2) -> c1 && c2);
		if (isAllRollback) {
			log.info("[RollbackAction doExecute] 当前所有参与者都是rollback，判定rollback执行完毕，清空事务环境 biz:" + context.getBiz() + " txId:" + context.getId());
			distributedTransactionRedisTools.clearTransactionContext(context.getBiz(), context.getId());
		} else {
			//	直接修改事务环境为rollback，并且通知所有人rollback
			distributedTransactionRedisTools.withJedis(jedis -> {
				Pipeline tx = jedis.pipelined();
				distributedTransactionRedisTools.updateContextStatus(tx, context.getBiz(), context.getId(), DistributedTransactionStatus.ROLLBACK);
				participantPublisher.sendParticipantRollback(tx, context.getBiz(), context.getId());
				tx.sync();
				return null;
			});
			log.info("[RollbackAction doExecute] 协调者收到rollback消息，广播rollback消息 biz:" + context.getBiz() + " txId:" + context.getId());
		}
	}

	
	/**
	 * 每个参与者都会清空自己的redis数据，如果已经拿不到参与者数据，说明大家都自己清除了
	 */
	@Override
	protected void noneParticipant(TransactionContext context) {
		log.info("[RollbackAction noneParticipant] 协调者rollback阶段找不到事务参与者，判定为大家都执行了回滚并且自行清理了redis，清空事务环境 biz:" + context.getBiz() + " txId:" + context.getId());
		distributedTransactionRedisTools.clearTransactionContext(context.getBiz(), context.getId());
	}
	
	
	


}
